<?php

namespace app\api\controller;

use addons\epay\library\Service;
use app\common\service\Order as OrderService;
use app\admin\model\Hall;
use app\admin\model\refund\Reason;
use app\common\controller\Api;
use app\admin\model\film\Info as FilmInfo;
use app\admin\model\Schedule as ScheduleModel;
use app\common\model\OrderTicket;
use app\admin\model\Order as OrderModel;
use app\admin\model\user\Coupons as UserCoupons;
use app\admin\model\Coupons;
use app\common\model\User;
use PHPQRCode\QRcode;
use think\Db;
use think\Exception;
use think\Log;
use think\Queue;
use think\Validate;
use app\admin\model\Winemenu;
// 加载基础 adapay 基础类
// SDK 初始化文件加载
//include_once  dirname(__FILE__). "/../../../extend/adapay/AdapaySdk/init.php";
//// 在文件中设置 DEBUG 为 true 时， 则可以打印日志到指定的日志目录下 LOG_DIR
//include_once  dirname(__FILE__). "/../../../extend/adapay/AdapaySdk/config.php";
/**
 * 订单接口
 */
class Order extends Api
{

    //如果$noNeedLogin为空表示所有接口都需要登录才能请求
    //如果$noNeedRight为空表示所有接口都需要验证权限才能请求
    //如果接口已经设置无需登录,那也就无需鉴权了
    //
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = [];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['*'];

    /**
     * 创建订单
     */
    public function create()
    {
        $schedule_id = $this->request->post('schedule_id',0);
        $select_seat = $this->request->post('select_seat', [], 'strip_tags');
        $is_makeup = $this->request->post('is_makeup',0);
        $make_time = $this->request->post('make_time','');
//        $select_seat = '[{"Xcoord":9,"Ycoord":8,"level":"comfortable"},{"Xcoord":11,"Ycoord":8,"level":"normal"},{"Xcoord":11,"Ycoord":10,"level":"normal"},{"Xcoord":6,"Ycoord":9,"level":"normal"},{"Xcoord":4,"Ycoord":7,"level":"comfortable"}]';
        $customer_name = $this->request->post('customer_name','');
        $customer_gender = $this->request->post('customer_gender',0);
        $customer_mobile = $this->request->post('customer_mobile','');

        $is_wine_menu = $this->request->post('is_wine_menu',0);
        $wine_menu_id = $this->request->post('wine_menu_id',0);
        $is_ice = $this->request->post('is_ice',0);
        if (!$customer_name || !$customer_gender || !$customer_mobile){
            $this->error('请完善顾客信息');
        }
        //验证手机号
        if (!Validate::regex($customer_mobile, "^1\d{10}$")) {
            $this->error('顾客手机号格式不正确');
        }

        if ($is_makeup){
            if (!$make_time){
                $this->error('请选择妆造时间');
            }
            $makeup_time_arr = explode(',',config('site.makeup_time'));
            if (!in_array($make_time,$makeup_time_arr)){
                $this->error('请选择正确的妆造时间');
            }
        }
        $info = ScheduleModel::where(['id'=>$schedule_id,'status'=>1])->find();
        if (!$info){
            $this->error('场次不存在');
        }
        if (!$select_seat){
            $this->error('请先选座');
        }
        if ($info['operating_status']==0){
            $this->error('该排期休息');
        }
        $select_seat = json_decode($select_seat,true);

        //验证酒套餐
        $wine_menu_price = 0;
        $wine_menu_name = '';
        if ($is_wine_menu){
            $Winemenu = new Winemenu();
            $wine_menu = $Winemenu->where(['id'=>$wine_menu_id,'status'=>1])->find();
            if (!$wine_menu){
                $this->error('酒套餐不存在/已下架');
            }
            $wine_menu_name = $wine_menu['name'];
            $wine_menu_price = config('site.wine_price');
        }
        $user = $this->auth->getUserinfo();

        $hall = Hall::where(['id'=>$info['hall_id']])->find();

        $select_seat_str = '';
        $order_amount = 0;
        $makeup_price = 0;
        foreach ($select_seat as $key=>$value)
        {

            // $has_ticket = OrderTicket::where(['schedule_id'=>$schedule_id,'x_coord'=>$value['Xcoord'],'y_coord'=>$value['Ycoord']])->whereIn('status',[0,1,2])->find();
            // if ($has_ticket){
            //     $this->error('座位已被选请重新选择');
            // }
            $has_ticket = OrderTicket::where(['schedule_id' => $schedule_id, 'x_coord' => $value['Xcoord'], 'y_coord' => $value['Ycoord']])->order(['id' => 'desc'])->find();
            if ($has_ticket && in_array($has_ticket['status'], [0, 1, 2])) {
                $this->error('座位已被选请重新选择');
            }
//            $decode_arr = json_decode($hall['seat_data'],true);
//            $select_seat_str .= $value['RowNum'].'排'.$value['ColumnNum'].'座 ';
            if ($value['level']=='normal')$order_amount += $info['seat_normal_price'];
            if ($value['level']=='vip')$order_amount += $info['seat_vip_price'];
        }
        $total_amount = $order_amount;
        //妆造价格
        if ($is_makeup){
            $makeup_price = config('site.makeup_price');
            $total_amount += $makeup_price;
        }
        //酒套餐金额
        $total_amount = bcMath($wine_menu_price,$total_amount,'+');
        //计算折扣
        $after_discount_fee = bcMath($total_amount,1,'*');
//        halt($after_discount_fee);
        //创建订单信息
        // 启动事务
        Db::startTrans();
        try{
            $now = time();

            $OrderModel = new OrderModel();
            $order_sn = build_order_no();
            $OrderModel->order_sn = $order_sn;
            $OrderModel->user_id = $user['id'];
            $OrderModel->schedule_id = $info['id'];
            $OrderModel->hall_id = $info['hall_id'];
            $OrderModel->total_amount = $total_amount;
            $OrderModel->total_fee = $after_discount_fee;
            $OrderModel->order_amount = $order_amount;
            $OrderModel->after_discount_fee = $after_discount_fee;
            $OrderModel->customer_name = $customer_name;
            $OrderModel->customer_gender = $customer_gender;
            $OrderModel->customer_mobile = $customer_mobile;
            $OrderModel->start_time = $info['full_start_time'];
            $OrderModel->is_makeup = $is_makeup;
            $OrderModel->make_time = $info['date'].' '.$make_time;
            $OrderModel->makeup_price = $makeup_price;
            $OrderModel->is_wine_menu = $wine_menu_id ? 1 : 0;
            $OrderModel->wine_menu_id = $wine_menu_id;
            $OrderModel->wine_menu_name = $wine_menu_name;
            $OrderModel->wine_menu_price = $wine_menu_price;
            $OrderModel->is_ice = $is_ice;
            $OrderModel->save();

            $order_id = $OrderModel->id;
            $order_ticket_arr = [];
//            $adminTicket = new Ticket();
            foreach ($select_seat as $key=>$value)
            {
//                $seat_data = $hall['seat_data'][$value['XCoord']][$value['YCoord']];
                if ($value['level']=='normal')$seat_price = $info['seat_normal_price'];
                if ($value['level']=='vip')$seat_price = $info['seat_vip_price'];

                $ticket_data = [
                    'schedule_id'=>$schedule_id,
                    'order_id'=>$order_id,
                    'user_id'=>$user['id'],
                    'hall_id'=>$info['hall_id'],
                    'seat_price'=>$seat_price,
                    'seat_type'=>$value['level'],
                    'x_coord'=>$value['Xcoord'],
                    'y_coord'=>$value['Ycoord'],
                    'row_num'=>$value['RowNum'],
                    'column_num'=>$value['ColumnNum'],
                    'seat_name'=>$value['alias'],
                    'createtime'=>$now,
                    'updatetime'=>$now
                ];
                array_push($order_ticket_arr,$ticket_data);
            }
            $OrderTicketModel = new OrderTicket();
            $OrderTicketModel->saveAll($order_ticket_arr);
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::error('创建订单系统错误:'.$e->getMessage());
            $this->error('系统错误');
        }
        //创建订单成功生成到期取消延迟队列
        Queue::later(180, 'app\job\CancelorderJob', $order_id, 'cancelorder');   // 取消订单延迟队列


        $this->success('创建订单成功',['order_sn'=>$order_sn]);
    }

    /*
     * 获取订单可用优惠券
     * */
    public function getOrderCoupon()
    {
        $order_id = $this->request->get('order_id',0);
        $user = $this->auth->getUserinfo();
        $OrderModel = new OrderModel();
        $order = $OrderModel->where(['id'=>$order_id,'status'=>0,'user_id'=>$user['id']])->find();
        if (!$order){
            $this->error('订单不存在');
        }
        $where['user_id'] = $user['id'];
        $UserCouponsModel = new UserCoupons();
        $list = $UserCouponsModel->with(['maincoupons'])->where($where)->select();
        if ($list)
        {
            foreach ($list as $key=>$value)
            {
                if ($value['maincoupons']['enough']>$order['after_discount_fee']){
                    //去掉不可用商品的券
                    array_splice($list, $key, 1);
//                    unset($value);

                }
            }
        }
        $this->success('订单可用优惠券',$list);
    }
    /*
     * 更新订单优惠活动
     * */
    public function updateOrderCoupon()
    {
        $order_id = $this->request->post('order_id',0);
        $coupon_id = $this->request->post('coupon_id',0);

        $user = $this->auth->getUserinfo();
        $OrderModel = new OrderModel();
        $order = $OrderModel->where(['id'=>$order_id,'status'=>0,'user_id'=>$user['id']])->find();
        if (!$order){
            $this->error('订单不存在');
        }

        $UserCouponsModel = new UserCoupons();
        $user_coupons = $UserCouponsModel->where(['user_id'=>$user['id'],'coupons_id'=>$coupon_id])->find();
        if (!$user_coupons){
            $this->error('优惠券不存在');
        }
        if ($user_coupons['use_order_id']>0){
            $this->error('优惠券已使用');
        }
        $CouponsModel =new Coupons();
        $coupon = $CouponsModel->where(['id'=>$user_coupons['coupons_id']])->find();

        if ($coupon['enough']>$order['after_discount_fee']){
            $this->error('不符合使用条件');
        }

        // 启动事务
        Db::startTrans();
        try{
            $order->total_fee = bcMath($order->total_fee,$coupon['amount'],'-');
            $order->coupon_id = $coupon_id;
            $order->coupon_fee = $coupon['amount'];
            $order->save();

            $user_coupons->use_order_id = $order_id;
            $user_coupons->usetime = time();
            $user_coupons->save();
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $this->error('系统错误:'.$e->getMessage());
        }


        $this->success('使用优惠券',['total_fee'=>$order->total_fee,'coupon_fee'=>$order->coupon_fee]);
    }

    /*
     * 订单支付
     * */
    public function pay()
    {
        $order_sn = $this->request->post('order_sn');
        $paytype = $this->request->post('paytype', 'wechat');
        $method = $this->request->post('method', '');

        if (!$order_sn) {
            $this->error(__('Invalid parameters'));
        }
        $user = $this->auth->getUserinfo();
        $orderModel = new orderModel();
        $order = $orderModel
            ->where('order_sn', $order_sn)
            ->where('user_id', $user['id'])
            ->where('status', 0)
            ->find();

        if(empty($order)){
            $this->error('订单不存在或已过期');
        }

        $order_sn = $order['order_sn'];
        if (empty($order)) {
            $this->error(__('No results were found'));
        }

        $ticket = OrderTicket::where('order_id', $order['id'])->whereIn('status',[0,1,2])->select();
        if ($ticket) {
            foreach ($ticket as $key => $value) {
                $has_ticket = OrderTicket::where('order_id','<>',$order['id'])->where(['schedule_id'=>$order['schedule_id'],'x_coord'=>$value['x_coord'],'y_coord'=>$value['y_coord']])->whereIn('status',[0,1,2])->select();
                if ($has_ticket){
                    $this->error('座位已被选请重新选择');
                }
            }
        }


        try {
            switch ($paytype) {
                case 'money':
                    // 余额支付
                    if ($order['total_fee']>$user['money']){
                        $this->error('余额不足');
                    }
                    OrderService::handlePaidOrder($order['order_sn'],$paytype);
                    $this->success('支付完成');
                    break;
                case 'wechat':

                    $notifyurl = request()->domain() . '/addons/epay/api/notifyx/paytype/wechat/order_type/'.$paytype;
                    if($method=='mp'){
                        $openid = $user['open_id'];
                    }else{
                        $openid = $user['openid'];
                    }

                    $pay_price = $order['total_fee'];
                    $order_no = $order['order_sn'];

                    $pay = Service::submitOrder($pay_price,$order_no,'wechat','支付',$notifyurl,'',$method,$openid);
//
                    $this->success('发起支付',$pay);
                    break;
                default:
                    // 执行代码块 n
                    break;
            }

        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /*
     * 修改订单信息
     * */
    public function updateOrder()
    {
        $order_id = $this->request->post('order_id',0);
        $customer_name = $this->request->post('customer_name','');
        $customer_gender = $this->request->post('customer_gender','');
        $customer_mobile = $this->request->post('customer_mobile','');

        if (!$customer_name || !$customer_gender || !$customer_mobile){
            $this->error('请完善顾客信息');
        }

        $user = $this->auth->getUserinfo();
        $orderModel = new orderModel();
        $order = $orderModel
            ->where('id', $order_id)
            ->where('user_id', $user['id'])
            ->where('status', 1)
            ->find();

        if (empty($order)) {
            $this->error('订单不存在');
        }

        $order->customer_name = $customer_name;
        $order->customer_gender = $customer_gender;
        $order->customer_mobile = $customer_mobile;
        $order->save();

        $this->success('修改成功');
    }

    /*
     * 改签
     * */
    public function rebook()
    {
        die;
        $order_id = $this->request->post('order_id',0);
        $schedule_id = $this->request->post('schedule_id',0);
        $select_seat = $this->request->post('select_seat', [], 'strip_tags');
        if (!$select_seat){
            $this->error('请先选座');
        }
        $select_seat = json_decode($select_seat,true);
        $user = $this->auth->getUserinfo();
        $orderModel = new orderModel();
        $order = $orderModel
            ->where('id', $order_id)
            ->where('user_id', $user['id'])
            ->where('status', 1)
            ->find();

        if (empty($order)) {
            $this->error('订单不存在');
        }
        //验证订单开始时间是否在48小时内
        if ((strtotime($order['start_time'])-time())<(86400*3)){
            $this->error('距预约时间不足三天,请联系管理员');
        }

        $info = ScheduleModel::where(['id'=>$schedule_id,'status'=>1])->find();
        $hall = Hall::where(['id'=>$info['hall_id']])->find();

        $OrderTicketModel = new OrderTicket();

        $new_num = count($select_seat);
        $old_num = $OrderTicketModel->where(['order_id'=>$order['id']])->count();
        if ($new_num != $old_num){
            $this->error('新座数与原座数不一致请重新选择');
        }
        $order_amount = 0;
        foreach ($select_seat as $key=>$value)
        {

            $has_ticket = $OrderTicketModel->where(['schedule_id'=>$schedule_id,'x_coord'=>$value['Xcoord'],'y_coord'=>$value['Ycoord']])->whereIn('status',[0,1,2])->find();
            if ($has_ticket){
                $this->error('座位已被选请重新选择');
            }

            if ($value['level']=='normal')$order_amount += $info['seat_normal_price'];
            if ($value['level']=='vip')$order_amount += $info['seat_vip_price'];
        }
        //验证订单金额与新选座位金额是否一致
        if ($order_amount!=$order['order_amount']){
            $this->error('与原订单金额不一致请重新选择');
        }
        $make_time = explode(' ', $order['make_time']);

        // 启动事务
        Db::startTrans();
        try{
            //更新订单信息
            $now = time();

            $order->schedule_id = $info['id'];
            $order->hall_id = $info['hall_id'];
            $order->start_time = $info['full_start_time'];
            $order->make_time = $info['date'].' '.$make_time[1];
            $order->save();

            //删除原订单票信息
            $OrderTicketModel->where('order_id',$order_id)->delete();
            //新增新订单票信息
            $order_ticket_arr = [];
            foreach ($select_seat as $key=>$value)
            {
//                $seat_data = $hall['seat_data'][$value['XCoord']][$value['YCoord']];
                if ($value['level']=='normal')$seat_price = $info['seat_normal_price'];
                if ($value['level']=='vip')$seat_price = $info['seat_vip_price'];

                $ticket_data = [
                    'schedule_id'=>$schedule_id,
                    'order_id'=>$order_id,
                    'user_id'=>$user['id'],
                    'hall_id'=>$info['hall_id'],
                    'seat_price'=>$seat_price,
                    'seat_type'=>$value['level'],
                    'x_coord'=>$value['Xcoord'],
                    'y_coord'=>$value['Ycoord'],
                    'row_num'=>$value['RowNum'],
                    'column_num'=>$value['ColumnNum'],
                    'status'=>1,
                    'createtime'=>$now,
                    'updatetime'=>$now
                ];
                array_push($order_ticket_arr,$ticket_data);
            }
            $OrderTicketModel->saveAll($order_ticket_arr);
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::error('改签订单系统错误:'.$e->getMessage());
            $this->error('系统错误');
        }

        $this->success('改签成功');
    }
    /*
     * 打印电影票
     * */
    public function printTicket()
    {
        $order_id = $this->request->param('order_id');
        $user = $this->auth->getUserinfo();
        $orderModel = new orderModel();
        $order = $orderModel
            ->where('id', $order_id)
            ->where('user_id', $user['id'])
            ->where('status', 1)
            ->find();

        if (empty($order)) {
            $this->error(__('No results were found'));
        }


        $this->success('出票成功');
    }

    /*
     * 退款原因
     * */
    public function refundReason()
    {
        $list = Reason::all();
//        // 加载基础 adapay 基础类
//        // SDK 初始化文件加载
//        include_once  dirname(__FILE__). "/../../../extend/adapay/AdapaySdk/init.php";
//        // 在文件中设置 DEBUG 为 true 时， 则可以打印日志到指定的日志目录下 LOG_DIR
//        include_once  dirname(__FILE__). "/../../../extend/adapay/AdapaySdk/config.php";
//halt(dirname(__FILE__). "/../../../extend/adapay/AdapaySdk/init.php");
        $epay = get_addon_config('epay');
        halt($epay);
        $this->success('退款原因',$list);
    }

    /*
     * 申请退款
     * */
    public function refund()
    {
        $order_id = $this->request->param('order_id');
        $refund_reason = $this->request->param('refund_reason','');
        if (!$refund_reason){
            $this->error('请选择退款原因');
        }
        $user = $this->auth->getUserinfo();
        $orderModel = new orderModel();
        $order = $orderModel
            ->where('id', $order_id)
            ->where('user_id', $user['id'])
            ->where('status', 1)
            ->find();

        if (empty($order)) {
            $this->error(__('No results were found'));
        }

        $order->refund_status = 1;
        $order->refund_reason = $refund_reason;
        $order->refund_fee = $order['total_fee'];
        $order->save();

        $this->success('提交成功');
    }


    /*
     * 订单取消
     * */
    public function cancel()
    {
        $order_id = $this->request->post('order_id',0);
        $user = $this->auth->getUserinfo();
        $where['id'] = $order_id;
        $where['user_id'] = $user['id'];
        $where['status'] = 1;
        $orderModel = new orderModel();
        $order = $orderModel->where($where)->find();
        if (!$order){
            $this->error('订单不存在');
        }
        //验证订单开始时间是否在24小时内
        if ((strtotime($order['start_time'])-time())<(86400*1)){
            $this->error('距开场时间不足24小时，无法取消');
        }

        //退款
        if ($order['pay_type']=='money'){
            OrderService::handleCancelOrder($order['order_sn']);
        }elseif ($order['pay_type']=='wechat'){
            $refund_order = [
                'out_trade_no' => $order['order_sn'],
                'out_refund_no' => time(),
                'total_fee' => intval($order['total_fee']*100),
                'refund_fee' => intval($order['total_fee']*100),
                'refund_desc' => '订单退款',
                'type'=>'miniapp'
            ];
            Log::info('退款参数');
            Log::info($refund_order);
            $result = Service::refund($refund_order);
            if (isset($result['return_code'])){
                if ($result['return_code']=='SUCCESS'){
                    OrderService::handleCancelOrder($order['order_sn']);
                    $order->refund_result = json_encode($result);
                    $order->save();
                }else{
                    $this->error('退款失败:'.$result['return_code']);
                }
            }else{
                $this->error('退款失败:'.$result['return_msg']);
            }
        }


        $this->success('订单取消');
    }
    /*
     * 我的订单
     * */
    public function myOrderList()
    {
        $status = $this->request->get('status');
        $limit = $this->request->get('limit');
        $user = $this->auth->getUserinfo();

        $where = [];
        if ($status=='paid'){
            $where['status'] = 1;
        }elseif ($status=='refund'){
            $where['status'] = 3;
        }else{
            $where['status'] = ['in',[-1,1,2,3]];
        }
        $where['user_id'] = $user['id'];


        $orderModel = new orderModel();
        $list = $orderModel
            ->with(['hall','schedule'])
            ->where($where)
            ->order('id','desc')
            ->paginate($limit);
        if ($list){
            foreach ($list as $key=>&$value)
            {
                $value['image'] = cdnurl($value['hall']['image'],true);
                $ticket_arr = OrderTicket::where(['order_id'=>$value['id']])->select();
                $select_seat_str = '';
                $ticket_text_arr = [];
//                $value['ticket_text'] = '';
//                $value['ticket_arr'] = [];
                foreach ($ticket_arr as $k=>$v)
                {
//                    $seat_str = $v['row_num'].'排'.$v['column_num'].'座 ';
//                    $select_seat_str .= $seat_str;
                    array_push($ticket_text_arr,$v['seat_name']);
                }
                $value['ticket_arr'] = $ticket_text_arr;
                $value['ticket_text'] = $select_seat_str;
                $value['ticket_num'] = count($ticket_arr);
            }
        }
        $this->success('我的订单',$list);
    }

    /*
     * 订单详情
     * */
    public function orderDetail()
    {
        $order_id = $this->request->get('order_id',0);

        $user = $this->auth->getUserinfo();
        $where['user_id'] = $user['id'];
        $where['id'] = $order_id;
        $orderModel = new orderModel();
        $info = $orderModel
            ->with(['hall','schedule'])
            ->where($where)
            ->find();
        if (!$info){
            $this->error('订单不存在');
        }
        $info['image'] = cdnurl($info['hall']['image'],true);
        $ticket_arr = OrderTicket::where(['order_id'=>$info['id']])->select();
        $select_seat_str = '';
        $ticket_text_arr = [];
//                $value['ticket_text'] = '';
//                $value['ticket_arr'] = [];
        foreach ($ticket_arr as $k=>$v)
        {
            $seat_str = $v['row_num'].'排'.$v['column_num'].'座 ';
            $select_seat_str .= $seat_str;
            array_push($ticket_text_arr,$v['seat_name']);
        }
        $info['ticket_arr'] = $ticket_text_arr;
        $info['ticket_text'] = $select_seat_str;
        $info['ticket_num'] = count($ticket_arr);

        $Winemenu = new Winemenu();
        $wine_menu = $Winemenu->where(['id'=>$info['wine_menu_id']])->find();
        $info['wine_menu_des'] = $wine_menu ? $wine_menu['des'] : '';
        $this->success('订单详情',$info);
    }
    //生成二维码
    //2. 在生成的二维码中加上logo(生成图片文件)
    public function scerweima($text){

        $pathname = APP_PATH . '/../public/uploads/qrcode/';
        if(!is_dir($pathname)) { //若目录不存在则创建之
            mkdir($pathname,0777,true);
        }

        $errorCorrectionLevel = 'H';  //容错级别
        $matrixPointSize = 10;      //生成图片大小
        //生成二维码图片
        $abc = $text.'.png';
        $filename = $pathname.$abc;

        if (file_exists($filename)){
            return request()->domain().'/uploads/qrcode/'.$abc;
        }
        $url = request()->domain() ."?no=" . $text;
        QRcode::png($text,$filename , $errorCorrectionLevel, $matrixPointSize, 2);
        return request()->domain().'/uploads/qrcode/'.$abc;
    }
}
